package com.zhouchj.elasticsearch;


import com.zhouchj.elasticsearch.index.EsIndexOperate;
import com.zhouchj.elasticsearch.query.EsLambdaQueryChainWrapper;
import com.zhouchj.elasticsearch.update.EsLambdaUpdateChainWrapper;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;

/**
 * ES工具包工厂类
 *
 * @author zhouchj
 * @date 2023/8/18
 */
@Data
@RequiredArgsConstructor
public class EsToolkitFactory {

    private final ElasticsearchRestTemplate elasticsearchRestTemplate;

    private final RestHighLevelClient client;


    /**
     * lambda查询
     *
     * @param clazz 实体类class
     * @param <T>   实体类类型
     * @return EsLambdaQueryChainWrapper
     */
    public <T> EsLambdaQueryChainWrapper<T> lambdaQuery(Class<T> clazz) {
        IndexCoordinates index = elasticsearchRestTemplate.getIndexCoordinatesFor(clazz);
        return lambdaQuery(index, clazz);
    }


    /**
     * lambda查询
     *
     * @param indexName 索引名称
     * @param clazz     实体类class
     * @param <T>       实体类类型
     * @return EsLambdaQueryChainWrapper
     */
    public <T> EsLambdaQueryChainWrapper<T> lambdaQuery(String indexName, Class<T> clazz) {
        IndexCoordinates index = IndexCoordinates.of(indexName);
        return lambdaQuery(index, clazz);
    }


    /**
     * lambda查询
     *
     * @param index 索引名称
     * @param clazz 实体类class
     * @param <T>   实体类类型
     * @return EsLambdaQueryChainWrapper
     */
    public <T> EsLambdaQueryChainWrapper<T> lambdaQuery(IndexCoordinates index, Class<T> clazz) {
        return new EsLambdaQueryChainWrapper<>(index, clazz, elasticsearchRestTemplate);
    }


    /**
     * lambda更新
     *
     * @param clazz 实体类class
     * @param <T>   实体类类型
     * @return EsLambdaUpdateChainWrapper
     */
    public <T> EsLambdaUpdateChainWrapper<T> lambdaUpdate(Class<T> clazz) {
        IndexCoordinates index = elasticsearchRestTemplate.getIndexCoordinatesFor(clazz);
        return lambdaUpdate(index, clazz);
    }


    /**
     * lambda更新
     *
     * @param indexName 索引名称
     * @param clazz     实体类class
     * @param <T>       实体类类型
     * @return EsLambdaUpdateChainWrapper
     */
    public <T> EsLambdaUpdateChainWrapper<T> lambdaUpdate(String indexName, Class<T> clazz) {
        IndexCoordinates index = IndexCoordinates.of(indexName);
        return lambdaUpdate(index, clazz);
    }


    /**
     * lambda更新
     *
     * @param index 索引名称
     * @param clazz 实体类class
     * @param <T>   实体类类型
     * @return EsLambdaUpdateChainWrapper
     */
    public <T> EsLambdaUpdateChainWrapper<T> lambdaUpdate(IndexCoordinates index, Class<T> clazz) {
        return new EsLambdaUpdateChainWrapper<>(index, clazz, elasticsearchRestTemplate,client);
    }


    /**
     * 索引操作
     *
     * @param clazz 实体类class
     * @param <T>   实体类类型
     * @return IndexOperate
     */
    public <T> EsIndexOperate<T> indexOperate(Class<T> clazz) {
        IndexCoordinates index = elasticsearchRestTemplate.getIndexCoordinatesFor(clazz);
        return indexOperate(index, clazz);
    }


    /**
     * 索引操作
     *
     * @param indexName 索引名称
     * @param clazz     实体类class
     * @param <T>       实体类类型
     * @return IndexOperate
     */
    public <T> EsIndexOperate<T> indexOperate(String indexName, Class<T> clazz) {
        IndexCoordinates index = IndexCoordinates.of(indexName);
        return indexOperate(index, clazz);
    }


    /**
     * 索引操作
     *
     * @param index 索引名称
     * @param clazz 实体类class
     * @param <T>   实体类类型
     * @return IndexOperate
     */
    public <T> EsIndexOperate<T> indexOperate(IndexCoordinates index, Class<T> clazz) {
        return new EsIndexOperate<>(index, clazz, elasticsearchRestTemplate,client);
    }


}
